frontend/pages/e/[eventId].tsx (view raw)
1import {useState, useReducer, useEffect} from 'react';
2import {useTranslation} from 'react-i18next';
3import {useRouter} from 'next/router';
4import Layout from '../../layouts/Default';
5import Fab from '../../containers/Fab';
6import CarColumns from '../../containers/CarColumns';
7import NewCarDialog from '../../containers/NewCarDialog';
8import AddToMyEventDialog from '../../containers/AddToMyEventDialog';
9import Loading from '../../containers/Loading';
10import EventBar from '../../containers/EventBar';
11import useToastStore from '../../stores/useToastStore';
12import {initializeApollo} from '../../lib/apolloClient';
13import {
14 useUpdateEventMutation,
15 Event as EventType,
16 EventDocument,
17} from '../../generated/graphql';
18import useEventStore from '../../stores/useEventStore';
19
20interface Props {
21 event: EventType;
22}
23
24const Event = ({event}: Props) => {
25 const {t} = useTranslation();
26 const addToast = useToastStore(s => s.addToast);
27 const setEvent = useEventStore(s => s.setEvent);
28 const eventUpdate = useEventStore(s => s.event);
29 const setIsEditing = useEventStore(s => s.setIsEditing);
30 const [updateEvent] = useUpdateEventMutation();
31 const [isAddToMyEvent, setIsAddToMyEvent] = useState(false);
32 const [openNewCar, toggleNewCar] = useReducer(i => !i, false);
33
34 useEffect(() => {
35 if (event) setEvent(event as EventType);
36 }, [event]);
37
38 const onSave = async e => {
39 try {
40 const {id, ...data} = eventUpdate;
41 delete data.__typename;
42 delete data.cars;
43 await updateEvent({variables: {id, eventUpdate: data}});
44 setIsEditing(false);
45 } catch (error) {
46 console.error(error);
47 addToast(t('event.errors.cant_update'));
48 }
49 };
50
51 const onShare = async () => {
52 if (!event) return null;
53 // If navigator as share capability
54 if (!!navigator.share)
55 return await navigator.share({
56 title: `Caroster ${event.name}`,
57 url: `${window.location.href}`,
58 });
59 // Else copy URL in clipboard
60 else if (!!navigator.clipboard) {
61 await navigator.clipboard.writeText(window.location.href);
62 addToast(t('event.actions.copied'));
63 return true;
64 }
65 };
66
67 return (
68 <Layout
69 pageTitle={t('event.title', {title: event.name})}
70 menuTitle={t('event.title', {title: event.name})}
71 displayMenu={false}
72 >
73 <EventBar
74 event={event}
75 onAdd={setIsAddToMyEvent}
76 onSave={onSave}
77 onShare={onShare}
78 />
79 <CarColumns toggleNewCar={toggleNewCar} />
80 <Fab onClick={toggleNewCar} open={openNewCar} aria-label="add-car" />
81 <NewCarDialog open={openNewCar} toggle={toggleNewCar} />
82 <AddToMyEventDialog
83 event={event}
84 open={isAddToMyEvent}
85 onClose={() => setIsAddToMyEvent(false)}
86 />
87 </Layout>
88 );
89};
90
91export async function getServerSideProps(context) {
92 const {eventId} = context.query;
93 const apolloClient = initializeApollo();
94 const {data = {}} = await apolloClient.query({
95 query: EventDocument,
96 variables: {id: eventId},
97 });
98 const {event} = data;
99
100 return {
101 props: {
102 event,
103 meta: {
104 title: event?.name,
105 },
106 },
107 };
108}
109
110export default props => {
111 const router = useRouter();
112 const {eventId} = router.query;
113
114 if (!eventId) return null;
115
116 return <Event {...props} eventId={eventId} />;
117};